#!/bin/sh
#
# validate session-id
SESSION_ID=`echo "$1" | egrep "^[-0123456789abcdef]*$"`
if [ -z "$SESSION_ID" ]; then
  echo "Invalid sessionid"
  exit 1
fi

# parse other arguments
FROM_FILE="$2"
if [ -z "$FROM_FILE" ]; then
  echo "No source specified"
  exit 1
fi

TO_FILE="$3"
if [ -z "$TO_FILE" ]; then
  echo "No destination specified"
  exit 1
fi

# optional arguments
FUID="$4"
FGID="$5"
MODE="$6"

# set defaults for the optionals if needed
if [ -z "$MODE" ]; then
  MODE="0640"
fi
if [ -z "$FGID" ]; then
  FGID="0"
fi
if [ -z "$FUID" ]; then
  FUID="0"
fi

# create the rollback directory for this session if it didn't exist
if [ ! -d /var/opencore/conf/rollback/$SESSION_ID ]; then
  mkdir /var/opencore/conf/rollback/$SESSION_ID || {
    echo "Error creating rollback directory"
    exit 1
  }
fi

# generate the filename for the rollback-file
RBFN=`echo "$TO_FILE" | tr "./ " ___ | sed -e "s/^_//"`
RBFILE="/var/opencore/conf/rollback/$SESSION_ID/${RBFN}.rollback"

# depending on the status of the destination file, create the apropriate
# rollback-file
if [ -f "$TO_FILE" ]; then
  # we'll preserve the access bits. The worst that can happen is that
  # the user would end up with a copy of the file he could already read
  # since we're getting the original file contents through runas.
  ST=`stat -c "%a" "$TO_FILE"`
  echo "UPDATE $FUID $FGID $ST $TO_FILE" > $RBFILE || {
	  echo "I/O error"
	  exit 1
  }
	
  /var/opencore/tools/runas $FUID $FGID fcat "$TO_FILE" >> $RBFILE || {
  	  echo "I/O error"
  	  exit 1;
  }
  
else
  echo "CREATE $FUID $FGID $TO_FILE" > $RBFILE || { echo "I/O error"; exit 1; }
fi

# create a temporary file in the destination directory, we will write
# the new contents to this file first.
TO_PATH=`dirname "$TO_FILE"`
TMP_FILE=`/var/opencore/tools/runas $FUID $FGID /bin/mktemp -p "$TO_PATH" .install_file.XXXXXXXX`
if [ -z "$TMP_FILE" ]; then
  echo "Error creating temporary file"
  rm -f "$RBFILE"
  exit 1
fi
if [ ! -f "$TMP_FILE" ]; then
  echo "Error creating temporary file"
  rm -f "$RBFILE"
  exit 1
fi

# set permissions on the new file
/var/opencore/tools/runas $FUID $FGID /bin/chmod $MODE "$TMP_FILE" || {
	echo "Tempfile chmod failed"
	/var/opencore/tools/runas $FUID $FGID rm -f "$TMP_FILE"
  rm -f "$RBFILE"
	exit 1
}

# copy the source data into the temporary file
# the fcat is probably superfluous. The runas isn't.
/var/opencore/tools/fcat "$FROM_FILE" | \
	/var/opencore/tools/runas $FUID $FGID write "$TMP_FILE" || {
		echo "I/O error"
		/var/opencore/tools/runas $FUID $FGID /bin/rm -f "$TMP_FILE"
	    rm -f "$RBFILE"
		exit 1
	}

# make the temporary file the new active file
/var/opencore/tools/runas $FUID $FGID /bin/mv "$TMP_FILE" "$TO_FILE" || {
	echo "Tempfile install failed"
	/var/opencore/tools/runas $FUID $FGID /bin/rm -f "$TMP_FILE"
    rm -f "$RBFILE"
	exit 1
}
